package com.lichhao.common.dao;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.lichhao.common.model.BaseBean;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class BaseDao<T extends BaseBean> {

	@Autowired
	protected MongoTemplate mongoTemplate;

	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}

	/**
	 * 向数据库中插入数据，collection的名称由bean里的注解标明
	 * 
	 * @param bean
	 */
	public void addRecord(T bean) {
		mongoTemplate.insert(bean);
	}

	/**
	 * 从数据库中删除指定的数据
	 * 
	 * @param bean
	 */
	public void deleteRecord(T bean) {
		mongoTemplate.remove(bean);
	}

	/**
	 * 根据参数查询数据
	 * 
	 * @param map
	 * @return
	 */
	public T findRecord(T bean) {

		Map<String, Object> map = bean.toMap();
		Query query = new Query();
		Iterator<String> iterator = map.keySet().iterator();

		while (iterator.hasNext()) {
			String key = iterator.next();
			if(map.get(key)!=null){
				query.addCriteria(Criteria.where(key).is(map.get(key)));
			}
			
		}
		return mongoTemplate.findOne(query, getBeanClass());
	}

	/**
	 * 根据bean的主键查询并更行数据库中的记录
	 * 
	 * @param bean
	 */
	public void updateRecord(T bean) {
		Query query = new Query(Criteria.where(bean.getKeyName()).is(
				bean.getKeyValue()));
		Update update = new Update();

		Map<String, Object> map = bean.toMap();

		Iterator<String> iterator = map.keySet().iterator();

		while (iterator.hasNext()) {
			String key = iterator.next();
			update.set(key, map.get(key));
		}

		mongoTemplate.updateFirst(query, update, getBeanClass());
	}

	private Class<T> beanClass;

	public BaseDao() {
		Type genType = getClass().getGenericSuperclass();
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		beanClass = (Class) params[0];
	}

	public Class<T> getBeanClass() {
		return this.beanClass;
	}

}
